package com.atguigu.tingshu.common.minio.service.impl;

import com.atguigu.tingshu.common.minio.config.MinioProperties;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.minio.service.FileOpsService;
import com.atguigu.tingshu.common.util.MD5;
import io.minio.*;
import io.minio.errors.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.ErrorResponseException;
import org.springframework.web.multipart.MultipartFile;

/**
 * Author:huzhongkui
 * Date: 2025-01-14 星期二 13:58:30
 * Description:
 */
//@Service
@Slf4j
public class FileOpsServiceImpl implements FileOpsService {

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MinioClient minioClient;

    @Override
    public String fileUpload(MultipartFile file) {
        String picUrl = "";
        // x.x.png
        String originalFilename = file.getOriginalFilename();
        try {
            // 1.获取文件对象字节数组
            byte[] bytes = file.getBytes();
            // 1.1.将字节数组转成字符串
            String fileContentStr = new String(bytes);
            // 1.2.将字符串进行MD5加密
            String filePrefix = MD5.encrypt(fileContentStr);
            // 1.3.获取文件的后缀
            String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
            // 1.4.定义对象名
            String objectName = filePrefix + fileSuffix;
            // 2.对文件对象进行去重校验
            StatObjectArgs.Builder statObjectArgsBuilder = StatObjectArgs.builder();
            StatObjectArgs statObjectArgs = statObjectArgsBuilder
                    .bucket(minioProperties.getBucketName())
                    .object(objectName)
                    .build();
            try {
                minioClient.statObject(statObjectArgs);// 如果不抛出异常，则代表minio指定桶中的文件已经存在，反之对象不存在
                log.info("minio指定桶中的对象存在，不用上传，直接返回对象在mino中的地址");
                return  minioProperties.getEndpointUrl() + "/" + minioProperties.getBucketName() + "/" + objectName;
            } catch (Exception e) {
                log.info("minio指定桶中的对象不存在，可以上传");
                // 3.上传
                // 3.1 构建一个PutObjectArgsBuilder对象
                PutObjectArgs.Builder builder = PutObjectArgs.builder();
                PutObjectArgs putObjectArgs = builder
                        .bucket(minioProperties.getBucketName())
                        .object(objectName)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .build();
                // 3.2 真正上传
                minioClient.putObject(putObjectArgs);
                // 文件地址：虚拟机的ip地址:虚拟机的端口/桶的名字/对象名
                picUrl = minioProperties.getEndpointUrl() + "/" + minioProperties.getBucketName() + "/" + objectName;
                // 3.3 返回地址
                return picUrl;
            }
        } catch (Exception e) {
            log.error("文件上传到minio中失败：{}", e.getMessage());
            throw new GuiguException(201, "文件上传到minio中失败");
        }

    }
}
